import { Children, cloneElement, DetailedReactHTMLElement, isValidElement, ReactNode } from "react"

import { ComponentChild, ComponentChildren } from "./types"

const getElement = (list: any[], slotname: string, SlotProps: Record<string, any>) => {
	for (let i = 0; i < list.length; i++) {
		const node = list[i]
		let [key, element]: [string, ComponentChild] = ["deault", null]
		if (node && isValidElement(node)) {
			const el: any = node
			const slotname = el.props.slotname
			;[key, element] = [
				slotname,
				cloneElement(el, {
					slotname: slotname,
					...SlotProps
				})
			]
		}
		if (slotname === key) {
			return element
		}
	}
	return null
}

const getSlot = (children: ComponentChildren | ComponentChildren[], slotname: string, SlotProps: Record<string, any>) => {
	if (!children) {
		return null
	}
	const childrenArray = Children.toArray(children)
	const element = getElement(childrenArray, slotname, SlotProps)

	if (element && isValidElement(element)) {
		return element
	}
	return null
}
export const InnerSlot = (props: any) => {
	const { children, slotname, ...SlotProps } = props
	const slotNewProps = SlotProps
	let childSlot: any = children
	childSlot = getSlot(children, slotname, slotNewProps)
	console.log(123, childSlot)
	return childSlot
}
export const useSlot = (props: ReactNode) => {
	const childrenArray = Children.toArray(props)
	if (!childrenArray) return {} as Record<string, DetailedReactHTMLElement<any, HTMLElement>[]>
	return childrenArray.reduce((prev, child) => {
		if (!child || !isValidElement(child)) return prev
		const el: any = child
		const slotname = el.props.slotname || "others"
		const element = cloneElement(el, {
			slotname: slotname || "others",
			...el.props
		})
		return {
			...prev,
			[slotname]: prev[slotname] ? [...prev[slotname], element] : [element]
		}
	}, {} as Record<string, DetailedReactHTMLElement<any, HTMLElement>[]>)
}

export const Slot = (props: any): JSX.Element => {
	const { children, slotname, ...SlotProps } = props

	if (isValidElement(children as ComponentChildren)) {
		return cloneElement(children, {
			slotname: slotname,
			...children.props,
			...SlotProps
		})
	}
	return Children.count(children) > 1 ? children : null
}
